package com.google.code.p.restrpc.spring;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.remoting.support.RemoteExporter;
import org.springframework.remoting.support.RemoteInvocationTraceInterceptor;

import com.google.code.p.restrpc.core.RpcServiceRepository;

/**
 * @author dz
 */
public class RpcServiceExporter extends RemoteExporter implements
                                                      InitializingBean {
    
    private static final Log logger = LogFactory.getLog(RpcServiceExporter.class);
    
    private RpcServiceRemoteExporter remoteExporter;
    
    private String exporterName;
    
    private Class serviceClass;
    
    /**
     * 
     */
    @Override
    public String getExporterName() {
        if (StringUtils.isEmpty(exporterName)) {
            return super.getExporterName();
        }
        return exporterName;
    }
    
    /**
     * @param exporterName
     */
    public void setExporterName(String exporterName) {
        this.exporterName = exporterName;
    }
    
    /**
     * @return
     */
    public RpcServiceRemoteExporter getRemoteExporter() {
        return remoteExporter;
    }
    
    /**
     * @param remoteExporter
     */
    public void setRemoteExporter(RpcServiceRemoteExporter remoteExporter) {
        this.remoteExporter = remoteExporter;
    }
    
    /**
     * @return the serviceClass
     */
    public Class getServiceClass() {
        return serviceClass;
    }
    
    /**
     * @param serviceClass
     *            the serviceClass to set
     */
    public void setServiceClass(Class serviceClass) {
        this.serviceClass = serviceClass;
    }
    
    @Override
    protected Object getProxyForService() {
//        if (this.interceptors == null && this.registerTraceInterceptor == null) {
//            return getService();
//        }
        
        return super.getProxyForService();
    }
    
    /**
     * 
     */
    public void afterPropertiesSet() {
        if (null == serviceClass) {
            this.serviceClass = AopUtils.getTargetClass(getService());
        }
        
        if (RpcServiceRepository.getInstance().isRegistered(getExporterName())) {
            throw new RuntimeException("The RpcService[serviceName=" + getExporterName()
                                       + "] has been registered before!");
        }
        //
        RpcServiceRepository.getInstance()
                            .registerService(getExporterName(),
                                             getServiceClass(),
                                             getServiceInterface(),
                                             getProxyForService(),
                                             getService());
    }
    
}
